// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

use serde::{Deserialize, Serialize};
use std::fs; // 添加文件系统操作支持
use std::path::Path; // 路径操作支持

// 定义文件树结构
#[derive(Serialize, Deserialize, Debug)]
pub struct FileNode {
    pub name: String,
    pub path: String,
    pub is_dir: bool,
    pub children: Option<Vec<FileNode>>,
}

// 注释掉手动实现的文件读取相关结构
// 新增：读取文本文件返回结构
// #[derive(Serialize, Deserialize, Debug)]
// pub struct ReadTextResponse {
//     pub success: bool,
//     pub content: String,
// }

// 注释掉手动实现的文件读取函数
// 新增：读取指定绝对路径的文本文件
// #[tauri::command]
// fn read_text_file(abs_path: String) -> ReadTextResponse {
//     let mut path_buf = std::path::PathBuf::from(&abs_path);

//     // 尝试标准化路径，但失败时继续使用原路径
//     if let Ok(canon) = std::fs::canonicalize(&path_buf) {
//         path_buf = canon;
//     }

//     if !path_buf.exists() {
//         return ReadTextResponse {
//             success: false,
//             content: "文件不存在".to_string(),
//         };
//     }

//     if path_buf.is_dir() {
//         return ReadTextResponse {
//             success: false,
//             content: "目标是目录而不是文件".to_string(),
//         };
//     }

//     match fs::read(&path_buf) {
//         Ok(bytes) => {
//             // 使用 UTF-8 容错解码，避免因非 UTF-8 内容报错
//             let content = String::from_utf8_lossy(&bytes).to_string();
//             ReadTextResponse {
//                 success: true,
//                 content,
//             }
//         }
//         Err(e) => ReadTextResponse {
//             success: false,
//             content: format!("读取失败: {}", e),
//         },
//     }
// }
use tauri_plugin_fs::FsExt; // 添加 FsExt trait 导入

// 递归扫描目录生成文件树
fn scan_directory(path: &Path) -> Result<FileNode, String> {
    let name = path
        .file_name()
        .ok_or_else(|| "无法获取文件名".to_string())?
        .to_str()
        .ok_or_else(|| "文件名转换失败".to_string())?
        .to_string();

    let path_str = path
        .to_str()
        .ok_or_else(|| "路径转换失败".to_string())?
        .to_string();

    let is_dir = path.is_dir();

    if !is_dir {
        return Ok(FileNode {
            name,
            path: path_str,
            is_dir: false,
            children: None,
        });
    }

    let mut children = Vec::new();

    // 读取目录内容
    if let Ok(entries) = fs::read_dir(path) {
        for entry in entries {
            if let Ok(entry) = entry {
                if let Ok(node) = scan_directory(&entry.path()) {
                    children.push(node);
                }
            }
        }
    }

    // 对文件和目录进行排序（目录在前，按名称排序）
    children.sort_by(|a, b| {
        if a.is_dir && !b.is_dir {
            std::cmp::Ordering::Less
        } else if !a.is_dir && b.is_dir {
            std::cmp::Ordering::Greater
        } else {
            a.name.cmp(&b.name)
        }
    });

    Ok(FileNode {
        name,
        path: path_str,
        is_dir: true,
        children: Some(children),
    })
}

fn with_root_name(mut root: FileNode, new_name: String) -> FileNode {
    root.name = new_name;
    root
}

fn normalize_display_path(path: &std::path::Path) -> String {
    let raw = path.to_string_lossy().to_string();
    #[cfg(windows)]
    {
        let prefix = r"\\?\";
        if raw.starts_with(prefix) {
            return raw[prefix.len()..].to_string();
        }
    }
    raw
}

// Tauri命令：打开目录选择器并扫描文件系统
#[tauri::command]
async fn select_directory_and_scan(app: tauri::AppHandle) -> Result<FileNode, String> {
    // 使用Tauri 2.x的正确API路径
    use tauri_plugin_dialog::DialogExt;
    let file_path = app
        .dialog()
        .file()
        .blocking_pick_folder()
        .ok_or_else(|| "用户取消了目录选择".to_string())?;
    let path = file_path
        .as_path()
        .ok_or_else(|| "无法解析所选路径".to_string())?;

    // 扫描选择的目录
    let root = scan_directory(path)?;

    // 计算绝对路径字符串，用于作为根节点的名称
    let abs_path = std::fs::canonicalize(path).unwrap_or_else(|_| path.to_path_buf());
    let abs_name = normalize_display_path(&abs_path);

    Ok(with_root_name(root, abs_name))
}


    

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_fs::init())
        .plugin(tauri_plugin_opener::init())
        .plugin(tauri_plugin_dialog::init())
        .setup(|app| {
            // 配置文件系统权限
            let fs_scope = app.fs_scope();
            let _ = fs_scope.allow_directory("/", true); // 允许访问所有目录，并忽略结果
            
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![
            greet,
            select_directory_and_scan
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
